package db

import (
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"github.com/go-xorm/xorm"
	"log"
	"sync"
)

// XormConnPool 连接池结构
type XormConnPool struct {
	mu       sync.Mutex
	conns    chan *xorm.Engine
	factory  func() (*xorm.Engine, error)
	maxConns int
}

// NewXormConnPool 创建一个新的连接池
func NewXormConnPool(factory func() (*xorm.Engine, error), maxConns int) (*XormConnPool, error) {
	conns := make(chan *xorm.Engine, maxConns)
	for i := 0; i < maxConns; i++ {
		conn, err := factory()
		if err != nil {
			return nil, err
		}
		conns <- conn
	}
	return &XormConnPool{
		conns:    conns,
		factory:  factory,
		maxConns: maxConns,
	}, nil
}

// Get 获取一个连接
func (p *XormConnPool) Get() (*xorm.Engine, error) {
	p.mu.Lock()
	defer p.mu.Unlock()

	select {
	case conn := <-p.conns:
		return conn, nil
	default:
		return p.factory()
	}
}

// Release 释放一个连接
func (p *XormConnPool) Release(conn *xorm.Engine) {
	p.mu.Lock()
	defer p.mu.Unlock()

	select {
	case p.conns <- conn:
	default:
		conn.Close()
	}
}

var XormPool *XormConnPool

func Db() (*XormConnPool, error) {
	if XormPool != nil {
		return XormPool, nil
	}
	// 数据库连接工厂函数
	factory := func() (*xorm.Engine, error) {
		user := "g_g_01film"
		pass := "TtnWAzw35kHMPxhT"
		dbname := "g_g_01film"
		mysqlUrl := user + ":" + pass + "@tcp(127.0.0.1:3306)/" + dbname
		//"yingyin:yingyin@/yingyin"
		return xorm.NewEngine("mysql", mysqlUrl)
	}

	// 创建连接池
	pool, err := NewXormConnPool(factory, 5)
	if err != nil {
		log.Fatalf("Error creating connection pool: %v", err)
	}
	XormPool = pool
	return XormPool, err
}

// ShowAllTables 显示所有的table
func ShowDbAllTables() {
	db, _ := Db()
	engine, err := db.Get()
	info, err := engine.DBMetas()
	if err != nil {
		return
	}
	if err != nil {
		log.Println(err)
		return
	}
	for _, v := range info {
		log.Println(v.Name)
	}
}
func main() {
	//ShowAllTables()
	type User struct {
		Id   int64  `xorm:"pk notnull unique autoincr"`
		Name string `xorm:"varchar notnull"`
	}
	// 创建连接池
	pool, err := Db()

	// 获取连接
	conn, err := pool.Get()
	if err != nil {
		log.Fatalf("Error getting connection: %v", err)
	}

	user := User{}
	// 使用连接
	//rows, err := conn.Rows("SELECT id, name FROM user")

	rows, err := conn.Where("id >?", 1).Rows(user)
	if err != nil {
		log.Fatalf("Error querying database: %v", err)
	}
	defer conn.Close()

	for rows.Next() {
		fmt.Printf("User: %d, %s\n", user)
		if err := rows.Scan(&user); err != nil {
			log.Fatalf("Error scanning row: %v", err)
		}
		fmt.Printf("User: %d, %s\n", user)
	}
	// 释放连接
	pool.Release(conn)
}
